home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / KISS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-19  |  5.6 KB  |  236 lines

  1. /* Routines for AX.25 encapsulation in KISS TNC
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Modified by G1EMM 19/11/90 to support multi-port KISS mode.
  5.  */
  6. /* Mods by G1EMM */
  7.  
  8. #include "global.h"
  9. #include "commands.h"
  10. #include "mbuf.h"
  11. #include "iface.h"
  12. #include "kiss.h"
  13. #include "devparam.h"
  14. #include "slip.h"
  15. #include "asy.h"
  16. #include "pktdrvr.h"
  17. #include "kisspoll.h"
  18.  
  19. #if !defined(_lint)
  20. static char rcsid[] OPTIONAL = "$Id: kiss.c,v 1.17 1997/01/19 21:13:05 root Exp root $";
  21. #endif
  22.  
  23. static int kiss_stop (struct iface * iface);
  24.  
  25. #ifdef POLLEDKISS
  26. /* this line is to fake out the linker */
  27. void *polledkiss_fakeit = (void *) kiss_poller;        /*lint !e611 */
  28. #endif
  29.  
  30.  
  31. /* Send raw data packet on KISS TNC */
  32. int
  33. kiss_raw (struct iface *iface, struct mbuf *data)
  34. {
  35. register struct mbuf *bp;
  36.  
  37.     /* Put type field for KISS TNC on front */
  38.     if ((bp = pushdown (data, 1)) == NULLBUF) {
  39.         free_p (data);
  40.         return -1;
  41.     }
  42.     bp->data[0] = PARAM_DATA;
  43.     bp->data[0] |= uchar (iface->port << 4);    /*lint !e701 */
  44.     if (iface->port) {
  45.         iface->rawsndcnt++;
  46.         iface->lastsent = secclock ();
  47.     }
  48.     /* slip_raw also increments sndrawcnt */
  49.     (void) slip_raw (Slip[iface->xdev].iface, bp);
  50.     return 0;
  51. }
  52.  
  53.  
  54.  
  55. /* Process incoming KISS TNC frame */
  56. void
  57. kiss_recv (struct iface *iface, struct mbuf *bp)
  58. {
  59. char kisstype;
  60. struct iface *kissif;
  61. int port;
  62. struct mbuf **bpp = &bp;
  63. #ifdef RXECHO
  64. struct mbuf *bbp;
  65. #endif
  66.  
  67.  
  68.     kisstype = (char) PULLCHAR (bpp);
  69.     port = kisstype >> 4;            /*lint !e702 */
  70.  
  71.     if ((kissif = Slip[iface->xdev].kiss[port]) == NULLIF) {
  72.         free_p (bp);
  73.         return;
  74.     }
  75.     switch (kisstype & 0xf) {
  76.         case PARAM_DATA:
  77. #ifdef RXECHO
  78.             /* Now we can echo the packet if configured (see config.c) */
  79.             if (kissif->rxecho) {
  80.                 (void) dup_p (&bbp, bp, 0, len_p (bp));
  81.                 (void) (*kissif->rxecho->raw) (kissif->rxecho, bbp);
  82.             }
  83. #endif
  84.             ax_recv (kissif, bp);
  85.             break;
  86.         default:
  87.             free_p (bp);
  88.             break;
  89.     }
  90. }
  91.  
  92.  
  93.  
  94. /* Perform device control on KISS TNC by sending control messages */
  95. int32
  96. kiss_ioctl (struct iface *iface, int cmd, int set, int32 val)
  97. {
  98. struct mbuf *hbp;
  99. char *cp;
  100. int32 rval = 0L;
  101.  
  102.     /* At present, only certain parameters are supported by
  103.      * stock KISS TNCs. As additional params are implemented,
  104.      * this will have to be edited
  105.      */
  106.     switch (cmd) {
  107.         case PARAM_RETURN:
  108.         case PARAM_RETURN2:
  109.             set = 1;/* Note fall-thru */
  110.         case PARAM_TXDELAY:
  111.         case PARAM_PERSIST:
  112.         case PARAM_SLOTTIME:
  113.         case PARAM_TXTAIL:
  114.         case PARAM_FULLDUP:
  115.         case PARAM_HW:
  116.             if (!set) {
  117.                 rval = -1;    /* Can't read back */
  118.                 break;
  119.             }
  120.             /* Allocate space for cmd and arg */
  121.             if ((hbp = alloc_mbuf (2)) == NULLBUF) {
  122.                 free_p (hbp);
  123.                 rval = -1;
  124.                 break;
  125.             }
  126.             cp = (char *) hbp->data;
  127.             *cp++ = (char) cmd;
  128.             *cp = (char) val;
  129.             hbp->cnt = 2;
  130.             if (hbp->data[0] != (unsigned char) PARAM_RETURN)
  131.                 hbp->data[0] |= uchar(iface->port << 4);    /*lint !e701 */
  132.             if (iface->port) {
  133.                 iface->rawsndcnt++;
  134.                 iface->lastsent = secclock ();
  135.             }
  136.             /* Even more "raw" than kiss_raw */
  137.             (void) slip_raw (Slip[iface->xdev].iface, hbp);
  138.             rval = val;
  139.             break;
  140.         case PARAM_SPEED:    /* These go to the local asy driver */
  141.         case PARAM_DTR:
  142.         case PARAM_RTS:
  143.         case PARAM_UP:
  144.         case PARAM_DOWN:
  145. #ifdef UNIX
  146.         case PARAM_MIN:/* almost certainly not its intended use... */
  147. #endif
  148.             rval = asy_ioctl (iface, cmd, set, val);
  149.             break;
  150.         default:    /* Not implemented */
  151.             rval = -1;
  152.             break;
  153.     }
  154.     return rval;
  155. }
  156.  
  157.  
  158.  
  159. static int
  160. kiss_stop (struct iface *iface)
  161. {
  162.     Slip[iface->xdev].kiss[iface->port] = NULLIF;
  163.     return 0;
  164. }
  165.  
  166.  
  167.  
  168. /* Attach a kiss interface to an existing asy interface in the system
  169.  * argv[0]: hardware type, must be "kiss"
  170.  * argv[1]: master interface, e.g., "ax4"
  171.  * argv[2]: kiss port, e.g., "4"
  172.  * argv[3]: interface label, e.g., "ax0"
  173.  * argv[4]: maximum transmission unit, bytes
  174.  */
  175. int
  176. kiss_attach (int argc, char **argv, void *p OPTIONAL)
  177. {
  178. struct iface *if_asy, *if_kiss;
  179. int port;
  180.  
  181.     if ((if_asy = if_lookup (argv[1])) == NULLIF) {
  182.         tprintf ("Interface %s does not exist\n", argv[1]);
  183.         return -1;
  184.     }
  185.     /* Check for ASY type interface ! - WG7J */
  186.     if (if_asy->type != CL_AX25) {
  187.         tprintf ("Multidrop KISS not allowed in interface: %s\n", argv[1]);
  188.         return -1;
  189.     }
  190.     if (if_lookup (argv[3]) != NULLIF) {
  191.         tprintf ("Interface %s already exists\n", argv[4]);
  192.         return -1;
  193.     }
  194.     if ((port = atoi (argv[2])) == 0) {
  195.         tprintf ("Port 0 automatically assigned to interface %s\n", argv[1]);
  196.         return -1;
  197.     }
  198.     if (port < 1 || port > 15) {
  199.         tputs ("Ports 1 to 15 only\n");
  200.         return -1;
  201.     }
  202.     if (Slip[if_asy->xdev].kiss[port] != NULLIF) {
  203.         tprintf ("Port %d already allocated on interface %s\n", port, argv[1]);
  204.         return -1;
  205.     }
  206.     /* Create interface structure and fill in details */
  207.     if_kiss = (struct iface *) callocw (1, sizeof (struct iface));
  208.  
  209.     if_kiss->addr = if_asy->addr;
  210.     if_kiss->name = strdup (argv[3]);
  211.  
  212.     if (argc >= 5)
  213.         if_kiss->mtu = (int16) atoi (argv[4]);
  214.     else
  215.         if_kiss->mtu = if_asy->mtu;
  216.  
  217.     if_kiss->iface_metric = 1;
  218.     if_kiss->dev = if_asy->dev;
  219.     if_kiss->stop = kiss_stop;
  220.     (void) setencap (if_kiss, "AX25");
  221.     if_kiss->ioctl = kiss_ioctl;
  222.     if_kiss->raw = kiss_raw;
  223.     if (if_kiss->hwaddr == NULLCHAR)
  224.         if_kiss->hwaddr = mallocw (AXALEN);
  225.     if (if_kiss->ipcall == NULLCHAR)
  226.         if_kiss->ipcall = mallocw (AXALEN);
  227.     memcpy (if_kiss->ipcall, Mycall, AXALEN);
  228.     memcpy (if_kiss->hwaddr, Mycall, AXALEN);
  229.     if_kiss->xdev = if_asy->xdev;
  230.     if_kiss->next = Ifaces;
  231.     Ifaces = if_kiss;
  232.     if_kiss->port = port;
  233.     Slip[if_kiss->xdev].kiss[if_kiss->port] = if_kiss;
  234.     return 0;
  235. }
  236.